package org.xshop.service.impl;

import java.io.File;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.transaction.annotation.Transactional;
import org.xshop.mapper.TGoodsMapper;
import org.xshop.model.TGoods;
import org.xshop.model.TGoodsAttribute;
import org.xshop.model.TGoodsLimit;
import org.xshop.model.TGoodsPromotion;
import org.xshop.model.TMemberCollection;
import org.xshop.model.TMemberFootmark;
import org.xshop.model.TStore;
import org.xshop.service.ITGoodsService;
import org.xshop.service.ITMemberCollectionService;
import org.xshop.service.ITMemberFootmarkService;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.plugins.Page;
import com.weibo.api.motan.config.springsupport.annotation.MotanService;

import top.ibase4j.core.base.BaseServiceImpl;
import top.ibase4j.core.exception.BusinessException;
import top.ibase4j.core.support.Pagination;
import top.ibase4j.core.util.DataUtil;
import top.ibase4j.core.util.DateUtil;
import top.ibase4j.core.util.ExceptionUtil;
import top.ibase4j.core.util.InstanceUtil;
import top.ibase4j.core.util.LocationUtil;
import top.ibase4j.core.util.PageUtil;
import top.ibase4j.core.util.QrcodeUtil;
import top.ibase4j.core.util.UploadUtil;

/**
 * <p>
 * 商品 服务类
 * </p>
 *
 * @author ShenHuaJie
 * @since 2017-03-19
 */
@MotanService(interfaceClass = ITGoodsService.class)
@CacheConfig(cacheNames = "goods")
public class GoodsService extends BaseServiceImpl<TGoods, TGoodsMapper> implements ITGoodsService {
    @Autowired
    private StoreService storeService;
    @Autowired
    private GoodsAttributeService attributeService;
    @Autowired
    private GoodsLimitService limitService;
    @Autowired
    private GoodsPromotionService promotionService;
    @Autowired
    private ITMemberCollectionService memberCollectionService;
    @Autowired
    private ITMemberFootmarkService memberFootmarkService;

    @Override
    public Pagination<TGoods> getPage(Page<Long> ids) {
        Pagination<TGoods> page = super.getPage(ids);
        for (TGoods goods : page.getRecords()) {
            goods.setStore(storeService.queryById(goods.getStoreId()));
        }
        return page;
    }

    @Override
    @Transactional
    public TGoods update(TGoods record) {
        TGoods result = super.update(record);

        if (record.getId() != null) {
            try {
                File file = new File("/usr/temp");
                if (!file.exists()) {
                    file.mkdirs();
                }
                Map<String, Object> data = InstanceUtil.newHashMap();
                data.put("goodsId", result.getId());
                String qrcodeFilePath = QrcodeUtil.createQrcode("/usr/temp", JSON.toJSONString(data));
                String path = UploadUtil.remove2FDFS(qrcodeFilePath).getRemotePath();
                result.setQrCode(path);
                result = super.update(result);
            } catch (Exception e) {
                logger.error(ExceptionUtil.getStackTraceAsString(e));
            }
        }

        Map<String, Object> columnMap = InstanceUtil.newHashMap("goods_id", result.getId());

        attributeService.deleteByMap(columnMap);
        if (record.getAttributes() != null) {
            for (TGoodsAttribute attribute : record.getAttributes()) {
                attribute.setGoodsId(result.getId());
                attributeService.update(attribute);
            }
        }
        limitService.deleteByMap(columnMap);
        if (record.getLimit() != null) {
            record.getLimit().setGoodsId(result.getId());
            limitService.update(record.getLimit());
        }
        promotionService.deleteByMap(columnMap);
        if (record.getPromotion() != null) {
            record.getPromotion().setGoodsId(result.getId());
            promotionService.update(record.getPromotion());
        }
        return result;
    }

    @Override
    public TGoods queryById(Long id) {
        TGoods goods = super.queryById(id);

        if (goods != null) {
            goods.setStore(storeService.queryById(goods.getStoreId()));

            TGoodsAttribute attribute = new TGoodsAttribute();
            attribute.setGoodsId(goods.getId());
            goods.setAttributes(attributeService.queryList(attribute));

            TGoodsLimit limit = new TGoodsLimit();
            limit.setGoodsId(goods.getId());
            goods.setLimit(limitService.selectOne(limit));

            TGoodsPromotion promotion = new TGoodsPromotion();
            promotion.setGoodsId(goods.getId());
            goods.setPromotion(promotionService.selectOne(promotion));
        }
        return goods;
    }

    @Override
    @Transactional
    public TGoods updateData(TGoods record) {
        return super.update(record);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        Map<String, Object> columnMap = InstanceUtil.newHashMap("goods_id", id);
        attributeService.deleteByMap(columnMap);
        limitService.deleteByMap(columnMap);
        promotionService.deleteByMap(columnMap);
        columnMap = InstanceUtil.newHashMap("collection_id", id);
        memberCollectionService.deleteByMap(columnMap);
        super.delete(id);
    }

    @Override
    public List<TStore> getAllGoods(Map<String, Object> param) {
        Object pageNum = param.get("pageNum");
        if (pageNum != null) {
            param.put("pageIndex", pageNum);
        }
        Pagination<TGoods> page = super.query(param);
        BigDecimal lon = null;
        BigDecimal lat = null;
        if (DataUtil.isNotEmpty(param.get("mapLon")) && DataUtil.isNotEmpty(param.get("mapLat"))) {
            lon = new BigDecimal(param.get("mapLon").toString());
            lat = new BigDecimal(param.get("mapLat").toString());
        }
        List<TGoods> goodsList = page.getRecords();
        // 商店归属
        Map<Long, List<TGoods>> map = InstanceUtil.newLinkedHashMap();
        for (int i = 0; i < goodsList.size(); i++) {
            TGoods goods = page.getRecords().get(i);
            if (goods.getIsPromotion() == 1) {
                TGoodsPromotion promotion = goods.getPromotion();
                if (promotion != null) {
                    Date now = DateUtil.stringToDate(DateUtil.getDate());
                    if (!promotion.getStartTime().after(now) && !promotion.getEndTime().before(now)) {
                        goods.setSalePrice(promotion.getPrice());
                    }
                }
            }
            Long id = goods.getStore().getId();
            if (map.containsKey(id)) {
                map.get(id).add(goods);
            } else {
                List<TGoods> list = InstanceUtil.newArrayList();
                list.add(goods);
                map.put(id, list);
            }
        }
        List<TStore> storeList = InstanceUtil.newArrayList();
        for (Long id : map.keySet()) {
            List<TGoods> goods = map.get(id);
            TStore store = goods.get(0).getStore();
            if (lon == null && lat == null && store.getStoreLon() != null && store.getStoreLat() != null) {
                BigDecimal distance = new BigDecimal(
                    LocationUtil.getDistance(store.getStoreLon(), store.getStoreLat(), lon, lat));
                store.setDistance(distance.setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            for (TGoods tGoods : goods) {
                tGoods.setStore(null);
            }
            store.setGoods(goods);
            storeList.add(store);
        }
        if (lon != null && lat != null) {
            // 距离排序
            Collections.sort(storeList, new Comparator<TStore>() {
                @Override
                public int compare(TStore o1, TStore o2) {
                    return o1.getDistance().subtract(o2.getDistance()).intValue();
                }
            });
        }
        return storeList;
    }

    /* private BigDecimal getDispatchingFee(String dispatchingFee, int goodsNum)
     * { BigDecimal price = new BigDecimal(0); if
     * (!DataUtil.isNotEmpty(dispatchingFee)) { return price; } JSONArray arr =
     * JSON.parseArray(dispatchingFee); BigDecimal num = new BigDecimal(0); for
     * (int i = 0; i < arr.size(); i++) { JSONObject fee = arr.getJSONObject(i);
     * num = fee.getBigDecimal("num"); price = fee.getBigDecimal("price"); if
     * (num.longValue() >= goodsNum) { break; } } return price; } */

    private String getAttributeHtml(List<TGoodsAttribute> list) {
        if (list.isEmpty()) {
            return "";
        }
        StringBuffer html = new StringBuffer();
        html.append("<p style='text-align: center;' ><table>");
        for (int i = 0; i < list.size(); i++) {
            TGoodsAttribute attribute = list.get(i);
            html.append("<tr><td>").append(attribute.getAttributeName()).append("</td><td>")
            .append(attribute.getAttributeValue()).append("</td></tr>");
        }
        html.append(" </table></p>");
        return html.toString();
    }

    @Override
    public TGoods getGoodsDetail(Map<String, Object> param) {
        Long id = Long.parseLong(param.get("id").toString());
        Object member = param.get("memberId");
        TGoods goods = queryById(id);
        if (goods == null) {
            return goods;
        }
        if (goods.getIsSale() != 1) {
            throw new BusinessException("商品未上架.");
        }
        goods.setAttribute(getAttributeHtml(goods.getAttributes()));

        if (goods.getIsPromotion() == 1) {
            TGoodsPromotion promotion = goods.getPromotion();
            if (promotion != null) {
                Date now = DateUtil.stringToDate(DateUtil.getDate());
                if (!promotion.getStartTime().after(now) && !promotion.getEndTime().before(now)) {
                    goods.setSalePrice(promotion.getPrice());
                }
            }
        }
        if (member == null) {
            return goods;
        }
        Long memberId = Long.parseLong(member.toString());
        // 商品收藏
        TMemberCollection memberCollection = new TMemberCollection();
        memberCollection.setMemberId(memberId);
        memberCollection.setCollectionId(id);
        memberCollection = memberCollectionService.selectOne(memberCollection);
        if (memberCollection == null) {
            // 未收藏
            goods.setCollect(0);
        } else {
            // 已收藏
            goods.setCollect(1);
        }
        // 加入我的足迹
        TMemberFootmark memberFootmark = new TMemberFootmark();
        memberFootmark.setCreateBy(memberId);
        memberFootmark.setGoodsId(id);
        TMemberFootmark temp = memberFootmarkService.selectOne(memberFootmark);
        if (temp != null) {
            memberFootmark.setId(temp.getId());
        }
        memberFootmarkService.update(memberFootmark);
        return goods;
    }

    @Override
    public Object getStoreGoods(Map<String, Object> param) {
        int pageNum = param.get("pageNum") == null ? 1 : Integer.parseInt(param.get("pageNum").toString());
        int pageSize = 10;
        param.put("offset", (pageNum - 1) * pageSize);
        param.put("limit", pageSize);
        param.put("typeIdI", param.get("type"));
        param.put("storeId", param.get("storeId"));
        String sort = param.getOrDefault("sort", "1").toString();
        if (sort.equals("2")) {
            param.put("sort", "sell_num");
        } else if (sort.equals("3")) {
            param.put("sort", "update_time");
        } else {
            param.put("sort", "sale_price");
            param.put("sortAsc", "Y");
        }
        Page<Long> page = PageUtil.getPage(param);
        page.setRecords(mapper.selectIdPage(page, param));
        return super.getPage(page);
    }
}
